#ifndef CAMERA_H
#define CAMERA_H

#include "log.h"
#include "types.h"
#include "scenegraph.h"

#include "math/m_vector.h"
#include "math/m_matrix.h"
#include "math/m_plane.h"
#include "math/m_quaternion.h"

// Thanks to jyk
// Thanks to Robert Crossland
// Thanks to Bruno 'Beosil' Heidelberger

namespace G3 {

extern float CAM_FPS_MAX_ROTX;

enum CAMERA_MODE {
	GCAM_MIN = 0,
	GCAM_FPS = 0,
	GCAM_SPECTATOR = 1,
	GCAM_6DOF = 2,
	GCAM_MAX = 2
};

class CAMERA: public ANIM_NODE {
    public:
        CAMERA (float X = 0.0f, float Y = 0.0f, float Z =0.0f);
        CAMERA (VEC3F Pos);

        virtual ~CAMERA () {}

        byte Mode;

        VEC3F Position;
        VEC3F LastPosition;

        QUATERNIONF Rotation;

        float FocusDistance;

//==============================================================================
// Resets camera to a position
//==============================================================================
        void Reset (VEC3F Pos);

//==============================================================================
// Sets camera mode
//==============================================================================
        void SetMode (uint NewMode);

//==============================================================================
// Normalizes camera rotation quaternion
//==============================================================================
        void Normalize ();

//==============================================================================
// Rotates the camera around an axis
//==============================================================================
        void RotateX (float Angle);
        void RotateY (float Angle);
        void RotateZ (float Angle);

//==============================================================================
// Rotates the camera
//==============================================================================
        void RotateView (float Angle, VEC3F Axis);

//==============================================================================
// For rotating the camera with a mouse
//==============================================================================
        void DeltaRotate (float dX, float dY);

//==============================================================================
// Focuses camera on a point
//==============================================================================
		void FocusOn (VEC3F Point);

//==============================================================================
// Gets a camera matrix
//==============================================================================
        MATRIX4x4F GetRotationMatrix ();
        MATRIX4x4F GetViewMatrix ();

//==============================================================================
// Drags the camera by the Distance vector
//==============================================================================
        void Move (VEC3F Distance);

//==============================================================================
// Gets a local Camera vector
//==============================================================================
        VEC3F GetForwardVector ();
        VEC3F GetRightVector ();
        VEC3F GetUpVector ();

//==============================================================================
// Get the World Position of the camera
//==============================================================================
        VEC3F GetWorldPosition ();

//==============================================================================
// Gets the Near plane
//==============================================================================
        PLANE3F GetNearPlane ();

		void Render (float ElapsedTime);
		void Update (float ElapsedTime);

        CAMERA operator=(CAMERA Cam);
};

}

#endif
